/*
 */
package wat.ziszcommon.clientgui;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author tarni
 * Klasa bazowa do KAZDEJ funkcji implementowanej przez developera funkcjonalnosci
 *  klienckiej.  Funkcja (transakcja) powinna byc generalnie JPanelem + definiowac
 *  wewnatrz interfejs dziedziczacy z FunctionBase.BaseServStub - ktory ma byc
 *  podany jako parametr instancjacji klasy.
 *
 * Ow zdefiniowany interfejs powinien deklarowac wszystkie metody, jakie z klasy
 *  klienta maja byc wywolywane w klasie (stojacej po stronie) serwera. Odpowiednia
 *  klasa serwerowa musi implementowac ten wlasnie interfejs.
 * Przy spelmnieniu w/w warunkow mechanizm komunikacji klienta samodzielnie
 *  zapewni przeslanie (zdanego) wywolania tych metod do serwera.
 */
public abstract class FunctionBase<ServStub extends FunctionBase.BaseServStub>
        extends MyJPanel {

   /*
    * Interfejs, ktory musi byc rozszerzony w klasach dziedziczacych z FunctionBase
    */
   abstract public interface BaseServStub {
   }

   private ServStub server;

   /*
    * sprawdza, czy podana klasa jest wlasciwym interfejsem do celow implementacji
    *  proxy klasy serwera, tzn.:
    *   - czy jest to podinterfejs FunctionBase.BaseServStub , oraz
    *   - czy jest to parametr instanjacji klasy dziedziczacej z FunctionBase
    */
   public static boolean isCorrectServerInterface(Class c) {
      // jesli jest to interfejs dziedziczacy z FunctionBase.BaseServStub
      if (c.isInterface() && BaseServStub.class.isAssignableFrom(c)) {
         //pobranie parametru generycznego (klasa zewnetrzna->parametryzowana nadklasa)
         Class surClass = c.getEnclosingClass();
         ParameterizedType f = (ParameterizedType) surClass.getGenericSuperclass();
         Type[] ty_arr = f.getActualTypeArguments();
         
         //liczba parametrow generycznych powinna byc 1 (jesli nie -> zle) ...
         if (ty_arr.length != 1)  return false;
         Class cPom = (Class)ty_arr[0];
         //... a parametr instancjacji powinien byc wlasnie tym otrzymanym do sprawdzenia interfejsem
         if (cPom.equals(c)) {
            //System.out.print("POTWIERDZENIE: " + c.getName() + " z " + surClass.getName() + "\n");
            return true;
         }
         //niby dobry interfejs, ale nie byl uzyty w instancjacji klasy zewnetrznej - nie to!
         //System.out.print("mimo wszystko niewlasciwa klasa \n");
         return false;
      } else {
         return false;
      }
   }


   protected FunctionBase(String name, MyJTree tree, ServStub ss) {
      super(name, tree);
      server = ss;
   }

   protected ServStub getServerObj() {
      return server;
   }
}
